package jc;
//一、优先级调度算法实现处理机调度的程序设计提示如下：
//( 1 ) 假设系统有n个进程，每个进程用一个进程控制块（PCB）来代表。进程控制块的格式如下表所示，且参数意义也相同。进程的优先数、到达时间和估计运行时间由用户程序任意设定，且优先数越低，优先级越高。调度时，总是选择优先级最高的进程运行。
//		（2）为了调度方便，设计一个指针指向就绪队列的第一个到达进程。另外再设一个当前运行进程指针，指向当前正运行的进程。
//		（3）处理机调度时，总是选择已经到达队列的优先级最高的进程运行。为了采用动态优先级调度，进程每运行一次，其优先级就减1。
//		（4）由于本题目是模拟实验，所以对被选中的进程并不实际启动运行，而只是执行如下操作：
//		1）优先数加1；
//		2）估计运行时间减1；
//		3）输出当前运行进程的名字。
//		用这三个操作来模拟进程的一次运行。
//		（5）进程运行一次后，应判断该进程的剩余运行时间是否为0，若不为0，且其优先级低于就绪队列的其他进程的优先级，则选择一个高优先级进程抢占CPU运行，若该进程的剩余运行时间为0，则将该进程的状态置为完成状态“C”，并撤出就绪队列。
//		（6）若就绪队列不为空，则重复上述的步骤（4）和（5）直到所有进程都运行完为止。
//		（7）在所设计的调度程序中，应包含显示或打印语句，以便显示或打印每次选中进程的名称及运行一次后进程的变化以及就绪队列中各进程排队情况。
//

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

public class Priority {

	public static void getMax(Queue<PCB> queue) {
		//找出优先级最高（优先级数最小）的进程
		int minPriorityNum = 100;
		int minArrivalTime = 100;
		for(PCB q : queue ) {
			if(q.getPriorityNum() < minPriorityNum) {
				minPriorityNum = q.getPriorityNum();	
			}			
		}
		//找出优先级最高且到达时间最早的进程
		for(PCB q : queue ) {
			if(q.getPriorityNum() == minPriorityNum && q.getArrivalTime() < minArrivalTime) {
				minArrivalTime = q.getArrivalTime();
			}
		}
		
		PCB first = queue.peek();
		for(int i = 0;i < queue.size();i++) {
			while(queue.peek().getPriorityNum() > minPriorityNum) {
				queue.offer(queue.peek());
				queue.poll();			
			}
			PCB q =  ((LinkedList<PCB>) queue).get(i);
			
			if(!q.equals(first)) {				
				if((q.getPriorityNum() == queue.peek().getPriorityNum()) && q.getArrivalTime() < queue.peek().getArrivalTime()) {					
					while(queue.peek().getArrivalTime() != minArrivalTime) {
						queue.offer(queue.peek());
						queue.remove(queue.peek());
						queue.remove(0);
						//i--;
					}										
				}else {						
					continue;
				}				
			}else {
				continue;
			}
		}				
	}
	
	public static void main(String[] args) {
		System.out.println("名字\t"+"到达时间\t"+"运行时间\t"+"优先级数\t"+"状态");
		Queue<PCB> queue = new LinkedList<PCB>();
		queue.offer(new PCB("a1"));
		queue.offer(new PCB("a2"));	
		queue.offer(new PCB("a3"));
		System.out.println("=======================================");
		
		while(!queue.isEmpty()) {
			//把优先级最高（优先级数小）的进程调到队首
			if(queue.size() > 1) {
				getMax(queue);			
			}
			
			if(!queue.isEmpty()) {
				//遍历队列，设置进程状态
				for(PCB q : queue) {
					if(q.equals(queue.peek())) {
						//队首
						q.setStatus("Working");
					}else {
						//非队首
						if(q.getStatus().equals("Working")) {
							q.setStatus("Ready");
						}												
					}
					//打印信息
					q.printInformation();
				}
				//进程运行
				queue.peek().run();
			}
			
			for(PCB q : queue) {
				if(q.getRunTime() == 0) {
					q.setStatus("End");					
				}
												
				if(q.getStatus().equals("End")) {
					System.out.println();
					//打印信息
					q.printInformation();
					System.out.print("==============="+q.getName()+"进程结束================");
					queue.poll();//检索并删除此队列的头，如果此队列为空，则返回 null 。
					break;
				}			
			}			
			System.out.println();	
			}				
		}		
	}


